package edu.gdpu.concurrent;

import sun.misc.Unsafe;

/**
 * @author mazebin
 * @date 2021年 07月16日 21:22:29
 * volatile禁止指令重排序演示代码
 */
public class Singleton {
    private  volatile  static  Singleton instance;
    public static  Singleton getInstance(){
        if(instance == null){
            synchronized (Singleton.class){
                if(instance == null){
                    instance = new Singleton();
                }
            }
        }
        return  instance;
    }

    public static void main(String[] args) {
        Singleton instance = getInstance();
    }
    /**
     instance = new Singleton();
     这段代码分为如下三个步骤：
     memory =allocate();//1.分配对象的内存空间
     ctorInstance(memory);//2.初始化对象
     instance = memory;//3.设置Instance指向刚分配的内存地址。
     而我们知道编译器核处理器会进行代码优化，而其中重要的一点是会将指令进行重排序。
     上边的代码经过重排序后可能会变为：
     memory = allocate();  // 1：分配对象的内存空间
     instance = memory;    // 3：设置instance指向刚分配的内存地址
     // 注意：此时对象尚未初始化
     ctorInstance(memory); // 2：初始化对象
而getInstance方法的字节码：
     Code:
     stack=2, locals=2, args_size=0
     0: getstatic     #2                  // Field instance:Ledu/gdpu/concurrent/Singleton;
     3: ifnonnull     37                  //如果不等于Null则跳转
     6: ldc           #3                  // class edu/gdpu/concurrent/Singleton
     8: dup                               //复制栈顶一个字长内容
     9: astore_0
     10: monitorenter                    //进入并获取对象监视器
     11: getstatic     #2                  // Field instance:Ledu/gdpu/concurrent/Singleton;
     14: ifnonnull     27
     17: new           #3                  // class edu/gdpu/concurrent/Singleton
     20: dup
     21: invokespecial #4                  // Method "<init>":()V
     24: putstatic     #2                  // Field instance:Ledu/gdpu/concurrent/Singleton;
     27: aload_0
     28: monitorexit                      //释放并退出对象监视器
     29: goto          37
     32: astore_1
     33: aload_0
     34: monitorexit                 //释放并退出对象监视器
     35: aload_1
     36: athrow
     37: getstatic     #2                  // Field instance:Ledu/gdpu/concurrent/Singleton;
     40: areturn

     */
}
